//
//  MyArray.swift
//  数据结构与算法
//
//  Created by 深圳链上时代 on 2020/11/18.
//

import Foundation

public struct MyArray<Element>: CustomStringConvertible {
    /// 数据
    private var data: [Element]
    /// 数组长度
    private var capacity = 0
    /// 已保存的数据个数
    private(set) var count = 0
    
    /// 构造方法
    /// - Parameters:
    ///   - defaultElement: 默认元素
    ///   - capacity: 数组长度
    init(defaultElement: Element, capacity: Int) {
        data = [Element](repeating: defaultElement, count: capacity)
        self.capacity = capacity
    }
    
    /// 根据 index，查找元素
    func find(at index: Int) -> Element? {
        // index必须在[0, count)
        guard index >= 0, index < count else {
            return nil
        }
        return data[index]
    }
    
    /// 根据 index，删除元素
    @discardableResult
    mutating func delete(at index: Int) -> Bool {
        // index必须在[0, count)
        guard index >= 0, index < count else {
            return false
        }
        // [index, count - 1) 从 index 开始，元素分别向前移动一位
        for i in index..<(count - 1) {
            data[i] = data[i + 1]
        }
        count -= 1
        return true
    }
    
    /// 根据 index 插入元素
    @discardableResult
    mutating func insert(value: Element, at index: Int) -> Bool {
        // index必须在[0, count) 且 count小于数组长度
        guard index >= 0, index < count, count < capacity else {
            return false
        }
        // [index, count - 1) 从后往前，元素分别向后移动一位
        for i in (index...(count - 1)).reversed() {
            data[i + 1] = data[i]
        }
        data[index] = value
        count += 1
        return true
    }
    
    /// 添加元素
    @discardableResult
    mutating func add(value: Element) -> Bool {
        // index必须在[0, count) 且 count小于数组长度
        guard count < capacity else {
            return false
        }
        data[count] = value
        count += 1
        return true
    }
    
    public var description: String {
        var desc = "["
        for i in 0..<count {
            desc += "\(data[i]), "
        }
        return desc.prefix(desc.count - 2) + "]"
    }
}
